Coverage Report

Created: 2021-08-28 18:14

D:\git\skunkworks\herald-for-cpp\herald\src\payload\simple\k.cpp
Line
Count
Source (jump to first uncovered line)
1
//  Copyright 2021 Herald Project Contributors
2
//  SPDX-License-Identifier: Apache-2.0
3
//
4
5
#include "herald/payload/simple/k.h"
6
#include "herald/payload/simple/f.h"
7
#include "herald/payload/simple/secret_key.h"
8
#include "herald/payload/simple/matching_key.h"
9
#include "herald/payload/simple/matching_key_seed.h"
10
#include "herald/payload/simple/contact_key.h"
11
#include "herald/payload/simple/contact_key_seed.h"
12
#include "herald/payload/simple/contact_identifier.h"
13
#include "herald/datatype/data.h"
14
#include "herald/datatype/time_interval.h"
15
16
namespace herald {
17
namespace payload {
18
namespace simple {
19
20
using namespace herald::datatype;
21
22
K::K() noexcept
23
  : keyLength(2048),daysFor(2000),periodsInDay(240), epoch(K::getEpoch())
24
0
{
25
0
  ;
26
0
}
27
28
K::K(const K& other) noexcept
29
  : keyLength(other.keyLength), 
30
    daysFor(other.daysFor),
31
    periodsInDay(other.periodsInDay),
32
    epoch(other.epoch)
33
0
{
34
0
  ;
35
0
}
36
37
K::K(int keyLength, int daysFor, int periodsInDay) noexcept
38
  : keyLength(keyLength),daysFor(daysFor),periodsInDay(periodsInDay), epoch(K::getEpoch())
39
0
{
40
0
  ;
41
0
}
42
43
K::K(int keyLength, int daysFor, int periodsInDay, TimeInterval epochBeginning) noexcept
44
  : keyLength(keyLength),daysFor(daysFor),periodsInDay(periodsInDay), epoch(epochBeginning)
45
0
{
46
0
  ;
47
0
}
48
49
0
K::~K() noexcept = default;
50
51
TimeInterval
52
0
K::getEpoch() noexcept {
53
0
  return TimeInterval(0); // Jan 1st 1970, seconds
54
0
}
55
56
int
57
0
K::day(Date on) const noexcept {
58
0
  return (long)(on - epoch) / 86400;
59
0
}
60
61
int
62
0
K::period(Date at) const noexcept {
63
0
  long seconds = (long)(at - epoch) % 86400;
64
0
  return (seconds * periodsInDay) / 86400; // more accurate
65
0
}
66
67
/// Low memory version of the key generator - generates key for a specified day
68
/// This saves memory use on Zephyr at the cost of CPU utilisation
69
MatchingKey
70
0
K::matchingKey(const SecretKey& secretKey, const int dayIdxFor) noexcept {
71
0
  // lazy initialisation
72
0
  MatchingKeySeed last(F::h(secretKey)); // value for day 2000
73
0
  MatchingKeySeed newSeed(32);
74
0
  for (int i = daysFor - 1;i >= dayIdxFor; --i) {
75
0
    // Calculate 1999 based on 2000, and so on, until we reach the current day's seed
76
0
    newSeed.assign(F::h(F::t(last)));
77
0
    last.assign(newSeed);
78
0
  }
79
0
  // At this point newSeed is the same as last, and last holds the seed for day dayIdxFor
80
0
  
81
0
  // matching key on day 0 is derived from matching key seed on day dayIdxFor and day dayIdxFor-1
82
0
  MatchingKeySeed minusOne(F::h(F::t(last)));
83
0
84
0
  return MatchingKey(F::h(F::xorData(last,minusOne)));
85
0
}
86
87
88
89
ContactKey
90
0
K::contactKey(const SecretKey& secretKey, const int dayFor, const int periodFor) noexcept {
91
0
  const int n = periodsInDay;
92
0
93
0
  auto mk(matchingKey(secretKey,dayFor));
94
0
95
0
  ContactKeySeed last(F::h(mk));
96
0
  ContactKeySeed lastMinusOne(32);
97
0
  for (int j = n - 1;j >= periodFor;j--) {
98
0
    lastMinusOne.assign(F::h(F::t(last)));
99
0
    last.assign(lastMinusOne);
100
0
  }
101
0
  // we now have lastMinusOne = contactKeySeed at periodFor
102
0
103
0
  // Day 0 key now
104
0
  ContactKeySeed minusOne(F::h(F::t(last)));
105
0
106
0
  return ContactKey(F::h(F::xorData(last, minusOne)));
107
0
}
108
109
ContactIdentifier
110
0
K::contactIdentifier(const SecretKey& secretKey, const int dayFor,const int periodFor) noexcept {
111
0
  auto ck(contactKey(secretKey,dayFor,periodFor));
112
0
  return ContactIdentifier(F::t(ck, 16));
113
0
}
114
115
// NOTE I'm keeping the old functions here in case we need to use a caching version on another platform
116
117
// const std::vector<MatchingKey>&
118
// K::matchingKeys(const SecretKey& secretKey) noexcept {
119
//   if (0 == mImpl->matchingKeySet.size()) {
120
//     // lazy initialisation
121
//     std::vector<MatchingKeySeed> matchingKeySeed(mImpl->daysFor + 1);
122
//     matchingKeySeed.reserve(mImpl->daysFor + 1);
123
//     matchingKeySeed[mImpl->daysFor] = MatchingKeySeed(F::h(secretKey));
124
//     for (int i = mImpl->daysFor - 1;i >=0; i--) {
125
//       matchingKeySeed[i].append(F::h(F::t(matchingKeySeed[i + 1])));
126
//     }
127
128
//     mImpl->matchingKeySet.reserve(mImpl->daysFor + 1);
129
//     for (int i = 0;i <= mImpl->daysFor;i++) {
130
//       mImpl->matchingKeySet.emplace_back();
131
//     }
132
    
133
//     // matching key on day 0 is derived from matching key seed on day 0 and day -1
134
//     MatchingKeySeed minusOne(F::h(F::t(matchingKeySeed[0])));
135
//     mImpl->matchingKeySet[0].append(F::h(F::xorData(matchingKeySeed[0],minusOne)));
136
    
137
//     // Matching key for day i is the hash of the matching key seed for day i xor i-1
138
//     for (int i = 1; i <= mImpl->daysFor;i++) {
139
//       mImpl->matchingKeySet[i].append(F::h(F::xorData(matchingKeySeed[i], matchingKeySeed[i - 1])));
140
//     }
141
//     // TODO set sk hash in this class to cache result
142
//   } else {
143
//     // TODO verify that the hash of the sk is the same as before
144
//   }
145
//   return mImpl->matchingKeySet;
146
// }
147
148
// const std::vector<ContactKey>
149
// K::contactKeys(const MatchingKey& matchingKey) noexcept {
150
//   const int n = mImpl->periodsInDay;
151
152
//   std::vector<ContactKeySeed> contactKeySeed;
153
//   contactKeySeed.reserve(n + 1);
154
155
//   for (int i = 0;i <= n;i++) {
156
//     contactKeySeed.emplace_back();
157
//   }
158
159
//   contactKeySeed[n].append(F::h(matchingKey));
160
//   for (int j = n - 1;j >= 0;j--) {
161
//     contactKeySeed[j].append(F::h(F::t(contactKeySeed[j + 1])));
162
//   }
163
164
//   std::vector<ContactKey> contactKey;
165
//   contactKey.reserve(n + 1);
166
167
//   for (int i = 0;i <= n;i++) {
168
//     contactKey.emplace_back();
169
//   }
170
  
171
//   for (int j = 1;j <= n;j++) {
172
//     contactKey[j].append(F::h(F::xorData(contactKeySeed[j],contactKeySeed[j - 1])));
173
//   }
174
175
//   // Day 0 key now
176
//   ContactKeySeed minusOne(F::h(F::t(contactKeySeed[0])));
177
//   contactKey[0].append(F::h(F::xorData(contactKeySeed[0], minusOne)));
178
179
//   return contactKey;
180
// }
181
182
// const ContactIdentifier
183
// K::contactIdentifier(const ContactKey& contactKey) noexcept {
184
//   return ContactIdentifier(F::t(contactKey, 16));
185
// }
186
187
188
}
189
}
190
}